package com.terry.bobobo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.text.SimpleDateFormat;

import weibo4j.Status;
import weibo4j.User;
import weibo4j.Weibo;
import weibo4j.WeiboException;
import weibo4j.http.AccessToken;
import weibo4j.http.RequestToken;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements
		android.view.View.OnClickListener, OnKeyListener {
	public static final String PREFS_NAME = "sinaweibo";
	private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
	private Weibo weibo = null;
	private RequestToken requestToken = null;
	private Button updateButton = null;
	private Button timelineButton = null;
	private EditText contentText = null;
	private TextView statusText = null;
	private TextView countText = null;
	private TextView nameText = null;
	private ImageView imageView = null;
	private ProgressBar progressBar = null;

	private String name = "";
	private Bitmap bm = null;

	private UIHandler updateUIHandler = new UIHandler();
	private WeiboHandler weiboHandler = null;

	private static final int ACTION_UPDATE = 1;
	private static final int ACTION_INFO = 2;
	private static final int ACTION_CHECK = 3;
	private static final int ACTION_PROMPT = 4;

	private static final int UPDATE_STATUS_UPDATED = 11;
	private static final int UPDATE_STATUS_UNUPDATED = 12;

	private static final int UPDATE_INFO = 13;
	private static final int UPDATE_ERROR = 14;
	private static final int UPDATE_ALERT = 15;

	private static final int MENU_LOGOUT = 1;
	private static final int MENU_EXIT = 2;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		statusText = (TextView) findViewById(R.id.status);
		contentText = (EditText) findViewById(R.id.content);
		contentText.setOnKeyListener(this);
		contentText.addTextChangedListener(new ContentTextWatcher());
		updateButton = (Button) findViewById(R.id.update);
		updateButton.setOnClickListener(this);
		timelineButton = (Button) findViewById(R.id.btimeline);
		timelineButton
				.setOnClickListener(new android.view.View.OnClickListener() {

					@Override
					public void onClick(View arg0) {
						Intent intent = new Intent();
						intent.setClass(MainActivity.this,
								TimelineActivity.class);
						startActivity(intent);
					}
				});
		countText = (TextView) findViewById(R.id.count);
		imageView = (ImageView) findViewById(R.id.image);
		progressBar = (ProgressBar) findViewById(R.id.progress);
		nameText = (TextView) findViewById(R.id.name);

		System.setProperty("weibo4j.debug", "false");
		System.setProperty("weibo4j.oauth.consumerKey", Weibo.CONSUMER_KEY);
		System.setProperty("weibo4j.oauth.consumerSecret",
				Weibo.CONSUMER_SECRET);

		weibo = new Weibo();

		SharedPreferences user = getSharedPreferences(PREFS_NAME, 0);
		String token = user.getString("token", null);
		String secret = user.getString("secret", null);
		name = user.getString("name", "");
		String content = user.getString("content", "");
		contentText.setText(content);

		HandlerThread handlerThread = new HandlerThread(
				"sinaweibo_mainActivity");
		handlerThread.start();
		weiboHandler = new WeiboHandler(handlerThread.getLooper());

		boolean isNetworkAvaiable = isNetworkAvailable();

		if (token != null && secret != null) {
			weibo.setToken(token, secret);
			nameText.setText(name);
			try {
				FileInputStream fin = openFileInput("icon");
				bm = BitmapFactory.decodeStream(fin);
				if (bm != null) {
					imageView.setImageBitmap(bm);
				}
			} catch (FileNotFoundException e) {
				// Just Ignore...
			}
			updateButton.setEnabled(true);
			timelineButton.setEnabled(true);
		} else if (isNetworkAvaiable) {
			weiboHandler.sendEmptyMessage(ACTION_PROMPT);
		}

		if (!isNetworkAvaiable) {
			statusText.setText("No network avaliable!");
			statusText.setTextColor(android.graphics.Color.RED);
			return;
		}

	}

	@Override
	protected void onStop() {
		SharedPreferences user = getSharedPreferences(PREFS_NAME, 0);
		SharedPreferences.Editor editor = user.edit();
		editor.putString("content", contentText.getText().toString());
		editor.commit();
		super.onStop();
	}

	private void showAlert() {
		AlertDialog.Builder alert = new AlertDialog.Builder(this);
		alert.setTitle("Input your pin");
		alert.setMessage("Type your pin from the web:");
		final EditText input = new EditText(this);
		input.setInputType(InputType.TYPE_CLASS_NUMBER);
		alert.setView(input);
		alert.setPositiveButton("OK", new OnClickListener() {

			@Override
			public void onClick(DialogInterface arg0, int arg1) {
				onInputToken(input.getText().toString());
			}
		});
		alert.show();
	}

	private void reCheckToken(String pin) {
		Message m = weiboHandler.obtainMessage();
		Bundle bundle = new Bundle();
		bundle.putString("pin", pin);
		m.what = ACTION_CHECK;
		m.setData(bundle);
		m.sendToTarget();
	}

	private void onInputToken(String pin) {
		reCheckToken(pin);
	}

	Runnable updateImageThread = new Runnable() {
		@Override
		public void run() {
			if (bm != null) {
				imageView.setImageBitmap(bm);
			}
			statusText.setText("");
		}

	};

	@Override
	public void onClick(View arg0) {
		updateStatus();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuItem deleteMenu = menu.add(0, MENU_LOGOUT, 0, "Delete Auth");
		deleteMenu.setIcon(android.R.drawable.ic_menu_delete);
		MenuItem exitMenu = menu.add(0, MENU_EXIT, 0, "Exit");
		exitMenu.setIcon(android.R.drawable.ic_menu_revert);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case MENU_EXIT:
			finish();
			break;
		case MENU_LOGOUT:
			SharedPreferences user = getSharedPreferences(PREFS_NAME, 0);
			SharedPreferences.Editor editor = user.edit();
			editor.putString("token", null);
			editor.putString("secret", null);
			editor.putString("name", null);
			editor.commit();
			finish();
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	private void updateStatus() {
		if (!updateButton.isEnabled())
			return;
		String status = contentText.getText().toString();
		if (status.length() == 0)
			return;
		Message msg = weiboHandler.obtainMessage();
		Bundle b = new Bundle();
		b.putString("status", status);
		msg.what = ACTION_UPDATE;
		msg.setData(b);
		msg.sendToTarget();
		progressBar.setVisibility(ProgressBar.VISIBLE);
		updateButton.setEnabled(false);
		timelineButton.setEnabled(true);
	}

	@Override
	public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
		if (arg1 == 23) {
			updateStatus();
		}
		return false;
	}

	class ContentTextWatcher implements TextWatcher {

		@Override
		public void afterTextChanged(Editable s) {
		}

		@Override
		public void beforeTextChanged(CharSequence s, int start, int count,
				int after) {
		}

		@Override
		public void onTextChanged(CharSequence s, int start, int before,
				int count) {
			try {
				int remain = (280 - String.valueOf(s).getBytes("GBK").length) / 2;
				updateButton.setEnabled(remain > 0);
				if (remain > 0)
					countText.setText(remain + " words Left");
				else
					countText.setText("Content too large...");

			} catch (UnsupportedEncodingException e) {
			}
		}

	};

	class UIHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			Bundle b = msg.getData();
			switch (msg.what) {
			case UPDATE_STATUS_UPDATED:
				String message = b.getString("message");
				statusText.setText(message);
				statusText.setTextColor(b.getInt("color"));
				contentText.setText("");
				updateButton.setEnabled(true);
				progressBar.setVisibility(ProgressBar.INVISIBLE);
				break;
			case UPDATE_STATUS_UNUPDATED:
				updateButton.setEnabled(true);
				progressBar.setVisibility(ProgressBar.INVISIBLE);
				break;
			case UPDATE_ERROR:
				statusText.setText(b.getString("message"));
				statusText.setTextColor(b.getInt("color"));
				updateButton.setEnabled(true);
				progressBar.setVisibility(ProgressBar.INVISIBLE);
				break;
			case UPDATE_INFO:
				updateButton.setEnabled(true);
				timelineButton.setEnabled(true);
				progressBar.setVisibility(ProgressBar.INVISIBLE);
				String name = b.getString("name");
				nameText.setText(name);
				break;
			case UPDATE_ALERT:
				showAlert();
				break;
			}

		}
	}

	class WeiboHandler extends Handler {
		public WeiboHandler() {

		}

		public WeiboHandler(Looper looper) {
			super(looper);
		}

		private void handleException(WeiboException e) {
			System.out.println(e.getStatusCode());
			System.out.println(e.getMessage());
			updateUIHandler.sendEmptyMessage(UPDATE_STATUS_UNUPDATED);
			Message message = updateUIHandler.obtainMessage();
			message.what = UPDATE_ERROR;
			Bundle bundle = new Bundle();
			String m = null;
			int statusCode = e.getStatusCode();
			switch (statusCode) {
			case -1:
				m = "Please check your network";
				break;
			case 400:
				m = "Please check your input";
				break;
			case 401:
				m = "You token invalid, please oauth";
				weiboHandler.sendEmptyMessage(ACTION_PROMPT);
				break;
			default:
				m = "Sorry, error occured, try again later";

			}
			bundle.putString("message", m);
			bundle.putInt("color", android.graphics.Color.RED);
			message.setData(bundle);
			message.sendToTarget();
		}

		@Override
		public void handleMessage(Message msg) {
			Bundle b = msg.getData();
			switch (msg.what) {
			case ACTION_UPDATE:
				String status = b.getString("status");
				try {
					Status s = weibo.updateStatus(status);
					Message message = updateUIHandler.obtainMessage();
					message.what = UPDATE_STATUS_UPDATED;
					Bundle bundle = new Bundle();
					bundle.putString("message", "Success! Updated: "
							+ sdf.format(s.getCreatedAt()));
					bundle.putInt("color", android.graphics.Color.GREEN);
					message.setData(bundle);
					message.sendToTarget();
				} catch (WeiboException e1) {
					handleException(e1);
				}
				break;
			case ACTION_INFO:
				String token = b.getString("token");
				String secret = b.getString("secret");
				weibo.setToken(token, secret);
				try {
					User u = weibo.verifyCredentials();
					URL url = u.getProfileImageURL();
					if (url != null) {
						bm = HttpUtils.getImage(u.getProfileImageURL());
						try {
							FileOutputStream fos = MainActivity.this
									.openFileOutput("icon", MODE_PRIVATE);
							bm.compress(Bitmap.CompressFormat.PNG, 100, fos);
							fos.flush();
							fos.close();
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
					name = u.getName();

					SharedPreferences user = getSharedPreferences(PREFS_NAME, 0);
					SharedPreferences.Editor editor = user.edit();
					editor.putString("token", token);
					editor.putString("secret", secret);
					editor.putString("name", name);
					editor.commit();
					Toast.makeText(MainActivity.this,
							"Oauth pass, saved token and secret!!",
							Toast.LENGTH_LONG).show();

					updateUIHandler.post(updateImageThread);

					Message message = updateUIHandler.obtainMessage();
					message.what = UPDATE_INFO;
					Bundle bundle = new Bundle();
					bundle.putString("name", name);
					message.setData(bundle);
					message.sendToTarget();
				} catch (WeiboException e) {
					handleException(e);
				}
				break;
			case ACTION_CHECK:
				String pin = b.getString("pin");
				try {
					AccessToken accessToken = requestToken.getAccessToken(pin);
					if (null == accessToken) {
						showAlert();
						String url = requestToken.getAuthorizationURL();
						Uri uri = Uri.parse(url);
						Intent it = new Intent(Intent.ACTION_VIEW, uri);
						startActivity(it);
					} else {
						Message m = weiboHandler.obtainMessage();
						Bundle bundle = new Bundle();
						bundle.putString("token", accessToken.getToken());
						bundle
								.putString("secret", accessToken
										.getTokenSecret());
						m.what = ACTION_INFO;
						m.setData(bundle);
						m.sendToTarget();
					}
				} catch (WeiboException e) {
					handleException(e);
				}
				break;
			case ACTION_PROMPT:
				try {
					weibo = new Weibo();
					requestToken = weibo.getOAuthRequestToken();
					Intent intent = new Intent();
					intent.setClass(MainActivity.this,
							PromptOauthActivity.class);
					intent.putExtra("url", requestToken.getAuthorizationURL());
					startActivity(intent);

					updateUIHandler.sendEmptyMessage(UPDATE_ALERT);
				} catch (WeiboException e) {
					handleException(e);
				}
				break;
			}
		}
	}

	public boolean isNetworkAvailable() {
		Context context = getApplicationContext();
		ConnectivityManager connectivity = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (connectivity == null) {
			return false;
		} else {
			NetworkInfo[] info = connectivity.getAllNetworkInfo();
			if (info != null) {
				for (int i = 0; i < info.length; i++) {
					if (info[i].getState() == NetworkInfo.State.CONNECTED) {
						return true;
					}
				}
			}
		}
		return false;
	}
}